/*
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

/*
 *
 *
 *
 *
 *
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/publicdomain/zero/1.0/
 */

package java.util.concurrent.locks;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import sun.misc.Unsafe;

/**
 * 提供一个框架, 用于实现依赖先进先出(FIFO)等待队列的阻塞锁和相关同步器(semaphores
 * 、events等). 此类被设计为大多数类型的同步器的有用基础, 这些同步器依赖于单个原子
 * {@code int}值来表示状态. 子类必须定义更改该状态的protected方法, 以及定义该状态
 * 在获取或释放该对象方面的含义. 考虑到这些, 这个类中的其他方法执行所有的派对和阻塞机制.
 * 子类可以维护其他状态字段, 但只有使用方法{@link #getState}、{@link #setState}、
 * 和{@link #compareAndSetState}操作的原子更新的{@code int}值才会被跟踪到同步.
 *
 * <p>子类应该定义为非public内部helper类, 用于实现其封闭来的synchronization属性.
 * 类{@code AbstractQueuedSynchronizer}不实现任何synchronization接口. 相反,
 * 它定义了{@link #acquireInterruptibly}等方法, 具体锁和相关同步器可以适当地调用
 * 这些方法来实现它们的public方法.
 *
 * <p>此类支持默认的<em>exclusive</em>模式和<em>shared</em>模式之一或两者.
 * 在exclusive模式下获取时, 其他现场尝试的获取无法成功. 多个现场获取shared模式可能
 * (但不一定)成功. 这个类不&quot;理解&quot;这些差异, 除了在机械意义上, 当shared模式
 * 获取成功时, 下一个等待线程(如果存在)也必须确定它是否也可以获取. 在 不同模式下等待的
 * 线程共享相同的FIFO队列. 通常, 实现子类只支持其中一种模式, 但两者都可以发挥作用,
 * 例如在{@link ReadWriteLock}中. 只支持exclusive或shared模式的子类不需要定义
 * 支持未使用模式的方法.
 *
 * <p>该类定义了一个嵌套的{@link ConditionObject}类, 该类可由支持exclusive模式的
 * 子类用作{@link Condition}实现, 对于该模式, 方法{@link #isHeldExclusively}
 * 报告是否相对于当前线程独占保持同步, 用当前{@link #getState}值调用的方法{@link #release}
 * 完全释放该对象, 而{@link #acquire}, 给定该保存的状态值, 最终将该对象恢复到其先前
 * 获取的状态. 没有{@code AbstractQueuedSynchronizer}方法会创建这样的条件, 所以
 * 如果不能满足这个约束, 就不要使用它. {@link ConditionObject}的行为当然取决于其
 * 同步器实现的语义.
 *
 * <p>此类提供内部队列的检查、检测和监视方法, 以及条件对象的类似方法. 这些可以根据需要
 * 导出到使用{@code AbstractQueuedSynchronizer}作为同步机制的类中.
 *
 * <p>此类的序列化只存储维护状态的底层原子整数, 因此反序列化的对象具有空线程对象.
 * 需要可序列化性的典型子类将定义一个{@code readObject}方法, 用于在反序列化时将其
 * 恢复到已知的初始状态.
 *
 * <h3>Usage</h3>
 *
 * <p>要使用该类作为同步器的基础, 通过使用{@link #getState}、
 * {@link #setState} and/or {@link #compareAndSetState}
 * 检查and/or修改同步状态, 重新定义以下方法(如果适用):
 *
 * <ul>
 * <li> {@link #tryAcquire}
 * <li> {@link #tryRelease}
 * <li> {@link #tryAcquireShared}
 * <li> {@link #tryReleaseShared}
 * <li> {@link #isHeldExclusively}
 * </ul>
 *
 * 默认情况下, 这些方法都会抛出{@link UnsupportedOperationException}.
 * 这些方法的实现必须是内部线程安全的, 通常应该是简短的, 而不是阻塞的. 定义
 * 这些方法是<em>唯一</em>支持的使用该类的方法. 所有其他方法都被声明为{@code final},
 * 因为它们不能被独立地改变.
 *
 * <p>你可能还会发现{@link AbstractOwnableSynchronizer}的继承方法对于跟踪
 * 拥有独占同步器的线程非常有用. 我们鼓励你使用它们 -- 这使得监视和诊断工具能够帮助
 * 用户确定哪些线程持有锁.
 *
 * <p>尽管这个类时基于内部FIFO队列的, 但它不会自动执行FIFO获取策略. 排它同步的核心是:
 *
 * <pre>
 * Acquire:
 *     while (!tryAcquire(arg)) {
 *        <em>如果线程尚未排队, 则将其键入队列</em>;
 *        <em>可能阻塞当前线程</em>;
 *     }
 *
 * Release:
 *     if (tryRelease(arg))
 *        <em>解除第一个排队线程的阻塞</em>;
 * </pre>
 *
 * (shared模式类型, 但可能涉及级联信号.)
 *
 * <p id="barging">因为acquire中的检查是在排队之前调用的, 所以新获取的线程可能会抢在
 * 其他被阻塞和排队的线程前面. 但是, 如果需要, 你可以定义{@code tryAcquire} and/or
 * {@code tryAcquireShared}, 通过内部调用一个或多个检查方法来禁用闯入, 从而提供
 * <em>公平</em>的FIFO获取顺序. 特别是, 大多数公平的同步器可以定义{@code tryAcquire}
 * 来返回{@code false}, 如果{@link #hasQueuedPredecessors}(一个专门为公平同步器
 * 使用的方法)返回{@code true}. 其他变化也是可能的.
 *
 * <p>默认的barging(也称为<em>贪婪</em>、<em>放弃</em>和<em>车队规避</em>)策略
 * 的吞吐量和可伸缩性通常是最高的. 虽然这不能保证公平或无饥饿, 但允许较早排队的线程在
 * 较晚排队的线程之前重新争用, 并且每次重新争用对传入线程都有一个无偏的成功机会. 此外,
 * 虽然获取不会在通常意义上"旋转", 但它们可能会在阻塞之前执行多次{@code tryAcquire}
 * 调用, 并穿插其他计算. 当独占同步仅短暂保持时, 这提供了旋转的大部分好处, 而当不保持时,
 * 则没有大部分责任. 如果需要, 你可以通过前面的调用来增强这一点, 以获取具有"fast-path"
 * 检查的方法, 可能会预检查{@link #hasContended} and/or {@link #hasQueuedThreads},
 * 以仅在同步器可能不被争用的情况下这样做.
 *
 * <p>该类为同步提供了一个高效和可扩展的基础, 不分是通过将其使用范围专门化到可以依赖于
 * {@code int}状态、获取和释放参数以及内部FIFO等待队列的同步器. 如果这还不够, 你可以使用
 * {@link java.util.concurrent.atomic atomic}类、你自己的自定义{@link java.util.Queue}
 * 类和{@link LockSupport}阻塞支持从较低的级别构建同步器.
 *
 * <h3>用法示例</h3>
 *
 * <p>下面是一个不可重入互斥锁类, 它使用值0表示未锁定状态, 1表示锁定状态. 虽然不可重入锁并不严格
 * 要求记录当前所有者线程, 但这个类还是这样做了, 一遍更容易监控使用状态. 它还支持条件, 并公开了一种
 * 检测方法:
 *
 *  <pre> {@code
 * class Mutex implements Lock, java.io.Serializable {
 *
 *   // 我们的内部helper class
 *   private static class Sync extends AbstractQueuedSynchronizer {
 *     // 报告是否处于锁定状态
 *     protected boolean isHeldExclusively() {
 *       return getState() == 1;
 *     }
 *
 *     // 如果状态为零, 则获取锁
 *     public boolean tryAcquire(int acquires) {
 *       assert acquires == 1; // Otherwise unused
 *       if (compareAndSetState(0, 1)) {
 *         setExclusiveOwnerThread(Thread.currentThread());
 *         return true;
 *       }
 *       return false;
 *     }
 *
 *     // 通过将state设置为零来释放锁
 *     protected boolean tryRelease(int releases) {
 *       assert releases == 1; // Otherwise unused
 *       if (getState() == 0) throw new IllegalMonitorStateException();
 *       setExclusiveOwnerThread(null);
 *       setState(0);
 *       return true;
 *     }
 *
 *     // Provides a Condition
 *     Condition newCondition() { return new ConditionObject(); }
 *
 *     // 反序列化properly
 *     private void readObject(ObjectInputStream s)
 *         throws IOException, ClassNotFoundException {
 *       s.defaultReadObject();
 *       setState(0); // reset to unlocked state
 *     }
 *   }
 *
 *   // 同步对象完成了所有艰苦的工作, 我们只是期待它.
 *   private final Sync sync = new Sync();
 *
 *   public void lock()                { sync.acquire(1); }
 *   public boolean tryLock()          { return sync.tryAcquire(1); }
 *   public void unlock()              { sync.release(1); }
 *   public Condition newCondition()   { return sync.newCondition(); }
 *   public boolean isLocked()         { return sync.isHeldExclusively(); }
 *   public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
 *   public void lockInterruptibly() throws InterruptedException {
 *     sync.acquireInterruptibly(1);
 *   }
 *   public boolean tryLock(long timeout, TimeUnit unit)
 *       throws InterruptedException {
 *     return sync.tryAcquireNanos(1, unit.toNanos(timeout));
 *   }
 * }}</pre>
 *
 * <p>这是一个类似{@link java.util.concurrent.CountDownLatch CountDownLatch}
 * 的latch类, 只不过它只需要一个{@code signal}就可以启动. 因为latch是非排它性的,
 * 所以它使用{@code shared}获取和释放方法.
 *
 *  <pre> {@code
 * class BooleanLatch {
 *
 *   private static class Sync extends AbstractQueuedSynchronizer {
 *     boolean isSignalled() { return getState() != 0; }
 *
 *     protected int tryAcquireShared(int ignore) {
 *       return isSignalled() ? 1 : -1;
 *     }
 *
 *     protected boolean tryReleaseShared(int ignore) {
 *       setState(1);
 *       return true;
 *     }
 *   }
 *
 *   private final Sync sync = new Sync();
 *   public boolean isSignalled() { return sync.isSignalled(); }
 *   public void signal()         { sync.releaseShared(1); }
 *   public void await() throws InterruptedException {
 *     sync.acquireSharedInterruptibly(1);
 *   }
 * }}</pre>
 *
 * @since 1.5
 * @author Doug Lea
 */
public abstract class AbstractQueuedSynchronizer
        extends AbstractOwnableSynchronizer
        implements java.io.Serializable {

    private static final long serialVersionUID = 7373984972572414691L;

    /**
     * 创建一个新的{@code AbstractQueuedSynchronizer}实例, 初始同步状态为0.
     */
    protected AbstractQueuedSynchronizer() { }

    /**
     * 等待队列节点类.
     *
     * <p>等待队列是"CLH"(Craig, Landin, and Hagersten) lock队列的一种变体.
     * CLH锁通常用于自旋锁. 相反, 我们将它们用于阻塞同步器, 但使用相同的基本策略,
     * 即在其节点的前驱中保存有关线程的一些控制信息. 每个节点中的"status"字段跟踪
     * 线程是否应该阻塞. 当一个节点的前驱释放时, 它会收到信号. 队列的每个节点充当
     * 特定通知样式的监视器, 持有单个瞪大线程. status字段并不控制线程是否被授予锁等.
     * 如果线程位于队列的第一个, 则可以尝试获取. 但做第一并不能保证成功; 它只赋予
     * 人们争抢的权利. 因此, 当前释放的竞争者线程可能需要重新等待.
     *
     * <p>要排队进入CLH锁, 需要自动地将其拼接为新的tail(队尾). 要离开队列, 只需要设置head字段.
     * <pre>
     *      +------+  prev +-----+       +-----+
     * head |      | <---- |     | <---- |     |  tail
     *      +------+       +-----+       +-----+
     * </pre>
     *
     * <p>插入到CLH队列只需要队"tail"进行单个原子操作, 因此存在从未排队到排队
     * 的简单原子分界点. 类似地, 脱离队列只涉及更新"head". 然而, 节点需要做更多的
     * 工作来确定谁是他们的后继者. 部分原因是为了处理由于超时和中断而可能取消的情况.
     *
     * <p>"prev"链接(在原来的CLH锁中没有使用)主要用于处理取消操作. 如果一个节点
     * 被取消, 它的后继节点(通常)被重新链接到一个未取消的前驱节点. 有关自旋锁的类似
     * 力学的解释, 请参阅 http://www.cs.rochester.edu/u/scott/synchronization/
     *
     * <p>我们还使用"next"链接来在还行阻塞机制. 每个节点的线程id都保存在自己的节点中,
     * 因此前驱节点通过遍历下一个链接来确定它是哪个线程, 从而通知要唤醒的下一个节点.
     * 后继者的缺点必须避免与新排队的节点竞争, 以设置其前驱的"next"字段. 当节点的后继节点
     * 为空时, 可以通过从自动更新的"tail"向后检查来解决这个问题. (或者换句话说, next链接
     * 是一种优化, 因此我们通常不需要向后扫描).
     *
     * <p>Cancellation为基本算法引入了一定的保守性. 由于我们必行轮询其他节点的取消, 因此
     * 我们可能无法注意到被取消的节点是在我们前面还是后面. 这是通过在取消时总是取消继任者的
     * 身份来解决的, 让他们能够稳定在新的前驱身上, 除非我们能够确定下一位未被取消的前驱来承担
     * 这一责任.
     *
     * <p>CLH队列需要一个虚拟的head节点才能启动. 但我们不会在构建时创建它们, 因为如果没有
     * 争用, 那将是浪费精力. 相反, 将构造节点, 并在第一次争用时设置head和tail指针.
     *
     * <p>等待条件的线程使用相同的节点, 但使用额外的链接. 条件只需要在简单(非并发)链接
     * 队列中链接节点, 因为它们只有在独占状态下才会被访问. 等待时, 将节点插入条件队列.
     * 收到信号后, 节点被转移到主队列. 状态字段的特殊值用于标记节点所在的队列.
     *
     * <p>感谢Dave Dice, Mark Moir, Victor Luchangco, Bill
     * Scherer and Michael Scott, 以及JSR-166专家组的成员, 为本类的设计提供了有用的
     * 想法, 讨论和批评.
     */
    static final class Node {
        /** 用于指示节点正在共享模式下等待的标记. */
        static final Node SHARED = new Node();
        /** 用于指示节点 正在独占模式下等待的标记. */
        static final Node EXCLUSIVE = null;

        /** waitStatus值, 指示线程已取消 */
        static final int CANCELLED =  1;
        /** waitStatus值, 指示后续线程需要取消标记 */
        static final int SIGNAL    = -1;
        /** waitStatus值, 指示线程正在等待条件 */
        static final int CONDITION = -2;
        /**
         * waitStatus值, 指示下一个acquireShared应无条件传播
         */
        static final int PROPAGATE = -3;

        /**
         * Status field, 仅采用以下值:
         *   SIGNAL:     此节点的后续节点被(或很快将被)阻止(通过park), 因此当前节点
         *               在释放或取消时必须取消其后续节点的标记. 为了避免竞争, 获取
         *               方法必须首先指示它们需要一个信号, 然后重试原子获取, 然后在
         *               失败时阻塞.
         *   CANCELLED:  由于超时或中断, 该节点被取消. 节点永远不会离开此状态.
         *               特别是, 具有取消节点的线程再也不会阻塞.
         *   CONDITION:  该节点当前位于条件队列中. 在传输之前, 它不会被用作同步队列
         *               节点, 此时状态将设置为0. (这里使用这个值与该字段的其他用法无关,
         *               但可以简化机制.)
         *   PROPAGATE:  releaseShared应该传播到其他节点. 这实在doReleaseShared中
         *               设置的(仅 针对head节点), 以确保传播继续进行, 即使其他操作已经介入.
         *   0:          以上都不是
         *
         * 这些值以数字形式排列, 以简化是会用. 非负值表示节点不需要发出信号. 所以, 大多数代码
         * 不需要检查特定的值, 只需要检查符号.
         *
         * 对于正常同步节点, 字段初始化为0, 对于条件节点, 字段则初始化为CONDITION.
         * 它使用CAS(或在可能的情况下, 无条件的volatile写入)进行修改.
         */
        volatile int waitStatus;

        /**
         * 链接到当前节点/线程检查waitStatus所依赖的前置节点. 在入队期间分配, 仅在出对
         * 时清空(为了GC). 此外, 在取消前一个节点时, 我们会在找到未被取消的前一个时短路,
         * 因为head节点从未被取消, 所以它将始终存在; 只有成功获取后, 节点才会成为head节点.
         * 被取消的线程永远不会成功获取, 线程只会取消自己, 而不会取消任何其他节点.
         */
        volatile Node prev;

        /**
         * 链接到当前节点/线程在发布时取消标记的后续节点. 在入队期间分配, 在绕过取消的
         * 前置任务时进行调整, 在出队时未null(为了GC). enq操作直到连接之后才分配前置
         * 节点的next字段, 所以看到next空字段并不一定意味着节点在队列的末尾. 然而,
         * 如果next字段显示未null, 我们可以从tail扫描prev以进行双重检查. 取消节点的
         * next字段被设置为指向节点本身, 而不是null, 以使isOnSyncQueue工作更轻松.
         */
        volatile Node next;

        /**
         * 将此节点排入对垒的线程. 在构造时初始化, 使用后为null.
         */
        volatile Thread thread;

        /**
         * 链接到等待条件或特殊值SHARED的next节点. 因为条件队列只有在独占模式下
         * 保持时才被访问, 所以我们只需要一个简单的链接队列来在节点等待条件时保持
         * 它们. 然后将它们转移到队列中以重新获取. 由于条件只能是独占的, 我们通过
         * 使用特殊值来指示共享模式来保存字段.
         */
        Node nextWaiter;

        /**
         * 如果节点正在共享模式下等待, 则return true.
         */
        final boolean isShared() {
            return nextWaiter == SHARED;
        }

        /**
         * 返回上一个节点, 如果为null则抛出NullPointerException.
         * 前置任务不能为null时使用. 可以取消null检查, 但存在null检查是为了帮助VM.
         *
         * @return 该节点的前驱
         */
        final Node predecessor() throws NullPointerException {
            Node p = prev;
            if (p == null)
                throw new NullPointerException();
            else
                return p;
        }

        Node() {    // 用于建立初始head或SHARED标记
        }

        Node(Thread thread, Node mode) {     // 由addWaiter使用
            this.nextWaiter = mode;
            this.thread = thread;
        }

        Node(Thread thread, int waitStatus) { // 由Condition使用
            this.waitStatus = waitStatus;
            this.thread = thread;
        }
    }

    /**
     * 等待队列的head, 已延迟初始化. 除了初始化之外, 它只能通过setHead进行修改.
     * 注: 如果head存在, 则保证其等待状态不会被取消.
     */
    private transient volatile Node head;

    /**
     * 等待队列的tail, 已延迟初始化. 仅通过方法enq进行修改, 以添加新的等待节点.
     */
    private transient volatile Node tail;

    /**
     * 同步状态.
     */
    private volatile int state;

    /**
     * 返回同步状态的当前值.
     * 此操作具有{@code volatile}读取的内存语义.
     * @return 当前state值
     */
    protected final int getState() {
        return state;
    }

    /**
     * 设置同步状态的值.
     * 此操作具有{@code volatile}写入的内存语义.
     * @param newState 新的state值
     */
    protected final void setState(int newState) {
        state = newState;
    }

    /**
     * 如果当前状态值等于预期值, 则原子化地将同步状态设置为给定的更新值.
     * 此操作具有{@code volatile}读写的内存语义.
     *
     * @param expect 期望的值
     * @param update 新的值
     * @return {@code true} 如果成功. 返回false表示实际值与预期值不相等.
     */
    protected final boolean compareAndSetState(int expect, int update) {
        // 请参阅下面的内部设置以支持此功能
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }

    // Queuing utilities

    /**
     * 旋转比使用timed park快的纳秒数. 粗略的估计足以在非常短的超时时间内提高响应性.
     */
    static final long spinForTimeoutThreshold = 1000L;

    /**
     * 将节点插入队列, 必要时进行初始化. 见上图.
     * @param node 要插入的节点
     * @return 节点的前驱
     */
    private Node enq(final Node node) {
        for (;;) {
            Node t = tail;
            if (t == null) { // 必须初始化
                if (compareAndSetHead(new Node()))
                    tail = head;
            } else {
                node.prev = t;
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }
            }
        }
    }

    /**
     * 为当前线程和给定模式创建和排队节点.
     *
     * @param mode Node.EXCLUSIVE表示排它, Node.SHARED表示共享
     * @return 新节点
     */
    private Node addWaiter(Node mode) {
        Node node = new Node(Thread.currentThread(), mode);
        // 尝试快速查询; 失败时备份到完整查询
        Node pred = tail;
        if (pred != null) {
            node.prev = pred;
            if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
            }
        }
        enq(node);
        return node;
    }

    /**
     * 将队列的head设置为node, 从而脱离队列. 只能由acquire方法调用.
     * 为了GC和抑制不必要的信号和遍历, 还将未使用的字段清空.
     *
     * @param node the node
     */
    private void setHead(Node node) {
        head = node;
        node.thread = null;
        node.prev = null;
    }

    /**
     * 唤醒节点的后继者(如果存在).
     *
     * @param node the node
     */
    private void unparkSuccessor(Node node) {
        /*
         * 如果状态为负(即, 可能需要信号), 尝试在预期信号时清除.
         * 如果此操作失败或状态被等待线程更改, 则没有问题.
         */
        int ws = node.waitStatus;
        if (ws < 0)
            compareAndSetWaitStatus(node, ws, 0);

        /*
         * 要unpark的线程保存在后继节点中, 后继节点通常是next节点. 但如果被取消
         * 或明显为null, 则从tail向后遍历以找到实际未被取消的后继者.
         */
        Node s = node.next;
        if (s == null || s.waitStatus > 0) {
            s = null;
            for (Node t = tail; t != null && t != node; t = t.prev)
                if (t.waitStatus <= 0)
                    s = t;
        }
        if (s != null)
            LockSupport.unpark(s.thread);
    }

    /**
     * 共享模式的释放动作 -- 信号后继并确保传播.
     * (注: 对于独占模式, 如果需要信号, 释放就相当于调用head的unparkSuccessor.)
     */
    private void doReleaseShared() {
        /*
         * 确保一个发布传播, 即使有其他正在进行的acquires/releases. 这以通常的方式
         * 进行, 如果需要信号, 则尝试unparkSuccessor of head. 但如果没有, 则将status
         * 设置为PROPAGATE, 以确保在发布时继续传播. 此外, 如果在执行此操作时添加了新节点,
         * 则必行进行循环. 此外, 与unparkSuccessor的其他用途不同, 我们需要在回到CAS重置
         * 状态是否失败, 如果失败, 则需要重新检查.
         */
        for (;;) {
            Node h = head;
            if (h != null && h != tail) {
                int ws = h.waitStatus;
                if (ws == Node.SIGNAL) {
                    if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
                        continue;            // 循环以重新检查cases
                    unparkSuccessor(h);
                }
                else if (ws == 0 &&
                        !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
                    continue;                // 在失败的CAS上循环
            }
            if (h == head)                   // 如果head发生变化则循环
                break;
        }
    }

    /**
     * 设置队列head, 并检查后续队列是否在共享模式下等待, 如果是, 则在设置了
     * propagate > 0或PROPAGATE状态时进行传播.
     *
     * @param node the node
     * @param propagate tryAcquireShared的返回值
     */
    private void setHeadAndPropagate(Node node, int propagate) {
        Node h = head; // 在下面记录旧head以进行检查
        setHead(node);
        /*
         * 如果出现以下情况, 请尝试发出下一个排队节点的信号:
         *   传播时由调用方指示的, 或者是由上一个操作记录的(在setHead之前或之后
         *   作为h.waitStatus)(注意: 这使用waitStatus的签名检查, 因为PROPAGATE
         *   状态可能会转换到SIGNAL.)
         * and
         *   下一个节点在共享模式下等待, 或者我们不知道, 因为它看起来是null
         *
         * 这两种检查的保守性可能会导致不必要的唤醒, 但只有在有多个竞争acquires/releases
         * 时, 所以大多数人现在或很快就需要信号.
         */
        if (propagate > 0 || h == null || h.waitStatus < 0 ||
                (h = head) == null || h.waitStatus < 0) {
            Node s = node.next;
            if (s == null || s.isShared())
                doReleaseShared();
        }
    }

    // Utilities for various versions of acquire

    /**
     * 取消正在进行的acquire尝试.
     *
     * @param node the node
     */
    private void cancelAcquire(Node node) {
        // 如果节点不存在, 则忽略
        if (node == null)
            return;

        node.thread = null;

        // 跳过已取消的前置任务
        Node pred = node.prev;
        while (pred.waitStatus > 0)
            node.prev = pred = pred.prev;

        // predNext是unsplice的明显节点. 如果没有, 下面的情况将失败, 在这种情况下,
        // 我们输掉了与另一个cacel或signal的比赛, 所以不需要进一步的操作.
        Node predNext = pred.next;

        // 这里可以使用物料间写入而不是CASA.
        // 在这个原子步骤之后, 其他节点可以跳过我们.
        // 之前, 我们不受其他线程的干扰.
        node.waitStatus = Node.CANCELLED;

        // 如果我们是tail, 那就把自己挪开.
        if (node == tail && compareAndSetTail(node, pred)) {
            compareAndSetNext(pred, predNext, null);
        } else {
            // 如果后继者需要信号, 试着设置pred的next链接, 这样它就会得到信号.
            // 否则唤醒它来传播.
            int ws;
            if (pred != head &&
                    ((ws = pred.waitStatus) == Node.SIGNAL ||
                            (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
                    pred.thread != null) {
                Node next = node.next;
                if (next != null && next.waitStatus <= 0)
                    compareAndSetNext(pred, predNext, next);
            } else {
                unparkSuccessor(node);
            }

            node.next = node; // help GC
        }
    }

    /**
     * 检查并更新获取失败节点的状态.
     * 如果线程阻塞, 返回true. 这是所有采集环路中的主要信号控制.
     * 要求pred == node.prev.
     *
     * @param pred 节点的前驱持有状态
     * @param node the node
     * @return {@code true} 如果线程应该阻塞
     */
    private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
        int ws = pred.waitStatus;
        if (ws == Node.SIGNAL)
            /*
             * 此节点已设置状态, 要求释放信号, 以便安全park.
             */
            return true;
        if (ws > 0) {
            /*
             * 前置任务已取消. 跳过前置任务并指示重试.
             */
            do {
                node.prev = pred = pred.prev;
            } while (pred.waitStatus > 0);
            pred.next = node;
        } else {
            /*
             * waitStatus必须为0或PROPAGATE. 表示我们需要信号, 但先别park.
             * 调用方需要重试以确保在park前无法获取.
             */
            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
        }
        return false;
    }

    /**
     * 方便的方法来中断当前线程.
     */
    static void selfInterrupt() {
        Thread.currentThread().interrupt();
    }

    /**
     * park的方便方法, 然后检查是否中断
     *
     * @return {@code true} if interrupted
     */
    private final boolean parkAndCheckInterrupt() {
        LockSupport.park(this);
        return Thread.interrupted();
    }

    /*
     * 各种各样的acquire方式, 包括独占/共享和控制模式. 每一种都大同小异,
     * 但又有令人恼火的不同. 由于异常机制(包括确保在tryAcquire抛出异常时取消)
     * 和其他控制的相互作用, 只有一点点的分解是可能的, 至少不会对性能造成太大的损害.
     */

    /**
     * 为已经在队列中的线程已独占不可中断模式获取.
     * 用于条件等待方法和acquire方法.
     *
     * @param node the node
     * @param arg acquire参数
     * @return {@code true} 如果在等待时被中断
     */
    final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                        parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    /**
     * 以独占可中断模式acquire.
     * @param arg acquire参数
     */
    private void doAcquireInterruptibly(int arg)
            throws InterruptedException {
        final Node node = addWaiter(Node.EXCLUSIVE);
        boolean failed = true;
        try {
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return;
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                        parkAndCheckInterrupt())
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    /**
     * 在独占定时模式下acquires.
     *
     * @param arg acquire参数
     * @param nanosTimeout max wait time
     * @return {@code true} if acquired
     */
    private boolean doAcquireNanos(int arg, long nanosTimeout)
            throws InterruptedException {
        if (nanosTimeout <= 0L)
            return false;
        final long deadline = System.nanoTime() + nanosTimeout;
        final Node node = addWaiter(Node.EXCLUSIVE);
        boolean failed = true;
        try {
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return true;
                }
                nanosTimeout = deadline - System.nanoTime();
                if (nanosTimeout <= 0L)
                    return false;
                if (shouldParkAfterFailedAcquire(p, node) &&
                        nanosTimeout > spinForTimeoutThreshold)
                    LockSupport.parkNanos(this, nanosTimeout);
                if (Thread.interrupted())
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    /**
     * 以共享不中断模式acquire.
     * @param arg the acquire argument
     */
    private void doAcquireShared(int arg) {
        final Node node = addWaiter(Node.SHARED);
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
                final Node p = node.predecessor();
                if (p == head) {
                    int r = tryAcquireShared(arg);
                    if (r >= 0) {
                        setHeadAndPropagate(node, r);
                        p.next = null; // help GC
                        if (interrupted)
                            selfInterrupt();
                        failed = false;
                        return;
                    }
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                        parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    /**
     * 以共享可中断模式acquire.
     * @param arg the acquire argument
     */
    private void doAcquireSharedInterruptibly(int arg)
            throws InterruptedException {
        final Node node = addWaiter(Node.SHARED);
        boolean failed = true;
        try {
            for (;;) {
                final Node p = node.predecessor();
                if (p == head) {
                    int r = tryAcquireShared(arg);
                    if (r >= 0) {
                        setHeadAndPropagate(node, r);
                        p.next = null; // help GC
                        failed = false;
                        return;
                    }
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                        parkAndCheckInterrupt())
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    /**
     * 在共享定时模式下acquire.
     *
     * @param arg acquire参数
     * @param nanosTimeout max wait time
     * @return {@code true} if acquired
     */
    private boolean doAcquireSharedNanos(int arg, long nanosTimeout)
            throws InterruptedException {
        if (nanosTimeout <= 0L)
            return false;
        final long deadline = System.nanoTime() + nanosTimeout;
        final Node node = addWaiter(Node.SHARED);
        boolean failed = true;
        try {
            for (;;) {
                final Node p = node.predecessor();
                if (p == head) {
                    int r = tryAcquireShared(arg);
                    if (r >= 0) {
                        setHeadAndPropagate(node, r);
                        p.next = null; // help GC
                        failed = false;
                        return true;
                    }
                }
                nanosTimeout = deadline - System.nanoTime();
                if (nanosTimeout <= 0L)
                    return false;
                if (shouldParkAfterFailedAcquire(p, node) &&
                        nanosTimeout > spinForTimeoutThreshold)
                    LockSupport.parkNanos(this, nanosTimeout);
                if (Thread.interrupted())
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    // Main exported methods

    /**
     * 尝试以独占模式acquire. 该方法应该查询对象的状态是否运行以独占模式获取它,
     * 如果允许则获取它.
     *
     * <p>此方法总是由执行acquire的线程调用. 如果此方法报告失败, 则acquire方法
     * 可能会将线程(如果尚未排队)放入队列, 直到其他线程发出release信号为止. 这可以
     * 用来实现方法{@link Lock#tryLock()}.
     *
     * <p>默认的实现抛出{@link UnsupportedOperationException}.
     *
     * @param arg acquire参数. 该值总是传递给acquire方法的值, 或者是在进入条件等待
     *        时保存的值. 否则该值是不解释的, 可以表示你喜欢的任何内容.
     * @return {@code true} 如果成功. 成功时, 该对象已被acquire.
     * @throws IllegalMonitorStateException 如果acquire将使此同步器处于非法状态.
     *         必须以一致的方式引发此异常, 同步才能正常工作.
     * @throws UnsupportedOperationException 如果不支持独占模式
     */
    protected boolean tryAcquire(int arg) {
        throw new UnsupportedOperationException();
    }

    /**
     * 尝试将状态设置为以独占模式反映发布.
     *
     * <p>此方法总是由支持release的线程调用.
     *
     * <p>默认实现抛出{@link UnsupportedOperationException}.
     *
     * @param arg release参数. 该值始终是传递给release方法的值, 或者是进入条件等待时
     *        的当前状态值. 该值在其他方面是不可解释的, 可以表示你喜欢的任何内容.
     * @return {@code true} 如果该对象现在处于完全release状态, 则任何等待的线程都可以
     *         尝试获取; 否则{@code false}.
     * @throws IllegalMonitorStateException 如果release将使此同步器处于非法状态.
     *         必须以一致的方式引发异常, 同步器才能正常工作.
     * @throws UnsupportedOperationException 如果不支持独占模式
     */
    protected boolean tryRelease(int arg) {
        throw new UnsupportedOperationException();
    }

    /**
     * 尝试在共享模式下acquire. 该方法应该查询对象的状态是否运行在共享模式下acquire,
     * 如果运行, 则进行acquire.
     *
     * <p>此方法总是由执行acquire的线程调用. 如果此方法报告失败, 则如果线程尚未排队,
     * 则获取方法可以对线程进行排队, 直到其他线程发出release信号.
     *
     * <p>默认实现抛出{@link UnsupportedOperationException}.
     *
     * @param arg acquire参数. 该值始终是传递给acquire方法的值, 或者是在进入
     *        等待条件时保存的值. 该值在其他方面是不可解释的, 可以表示你喜欢的任何内容.
     * @return 失败时为负值; 如果在共享模式下的acquire成功, 但没有后续的共享模式acquire
     *         能够成功, 则为零; 如果在共享模式下的acquire成功并且随后的共享模式acquire
     *         也可能成功, 则为正值, 在这种情况下, 随后的等待线程必须检查可用性.
     *         (通过支持三个不同的返回值, 该方法可以在获取有时只执行独占操作的情况下使用.)
     *         一旦成功, 该对象就被获取了.
     * @throws IllegalMonitorStateException 如果acquire将使此同步器处于非法状态.
     *         必须以一致的方式引发此异常, 同步器才能正常工作.
     * @throws UnsupportedOperationException 如果不支持共享模式
     */
    protected int tryAcquireShared(int arg) {
        throw new UnsupportedOperationException();
    }

    /**
     * 尝试将状态设置为反映共享模式下的release.
     *
     * <p>此方法总是由执行release的线程调用.
     *
     * <p>默认实现抛出{@link UnsupportedOperationException}.
     *
     * @param arg release参数. 该值始终是传递给release方法的值, 或者是
     *        进入条件等待时的当前状态值. 该值在其他方面是不可解释的, 可以
     *        表示你喜欢的任何内容.
     * @return {@code true} 如果共享模式的这种release可以允许等待acquire
     *         (享或独占)成功; 否则为{@code false}
     * @throws IllegalMonitorStateException 如果release将使此同步器处于非法状态.
     *         必须以一致的方式引发此异常, 同步器才能正常工作.
     * @throws UnsupportedOperationException 如果不支持共享模式
     */
    protected boolean tryReleaseShared(int arg) {
        throw new UnsupportedOperationException();
    }

    /**
     * 如果同步是针对当前(调用)线程已独占方式进行的, 则返回{@code true}. 该方法在
     * 每次调用非等待的{@link ConditionObject}方法时调用. (等待方法改为调用{@link #release}.)
     *
     * <p>默认实现抛出{@link UnsupportedOperationException}. 此方法仅在
     * {@link ConditionObject}方法内部调用, 因此如果不使用条件, 则无需定义.
     *
     * @return {@code true} 如果仅保持同步; 否则为{@code false}
     * @throws UnsupportedOperationException 如果不支持条件
     */
    protected boolean isHeldExclusively() {
        throw new UnsupportedOperationException();
    }

    /**
     * 以独占模式acquire, 忽略中断. 通过调用至少一次{@link #tryAcquire}来实现,
     * 成功后返回. 否则线程会排队, 可能会重复阻塞和取消阻塞, 调用{@link #tryAcquire}
     * 直到成功. 此方法可用于实现方法{@link Lock#lock}.
     *
     * @param arg acquire参数. 这个值被传递给{@link #tryAcquire}, 但在其他方面是
     *        不可以理解的, 可以表示任何你喜欢的东西.
     */
    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
                acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

    /**
     * 以独占模式acuqire, 如果中断则中止.
     * 通过首先检查中断状态, 然后至少调用一次{@link #tryAcquire}, 成功返回来实现.
     * 否则, 线程将排队, 可能会重复阻塞和取消阻塞, 调用{@link #tryAcquire}直到
     * 成功或线程中断. 此方法可用于实现方法{@link Lock#lockInterruptibly}.
     *
     * @param arg acquire参数. 该值被传递给{@link #tryAcquire}, 但在其他方面
     *        是不可理解的, 可以表示任何你喜欢的东西.
     * @throws InterruptedException 如果当前线程被中断
     */
    public final void acquireInterruptibly(int arg)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        if (!tryAcquire(arg))
            doAcquireInterruptibly(arg);
    }

    /**
     * 尝试以独占模式acquire, 如果中断则中止, 如果超过给定超时则失败. 通过首先检查
     * 中断状态, 然后至少调用一次{@link #tryAcquire}, 成功返回来实现. 否则, 线程
     * 将排队, 可能会重复阻塞和取消阻塞, 调用{@link #tryAcquire}, 直到成功或线程
     * 中断或超时. 此方法可用于实现方法{@link Lock#tryLock(long, TimeUnit)}.
     *
     * @param arg acquire参数.  该值被传递给{@link #tryAcquire}, 但在其他方面
     *        是不可理解的, 可以表示任何你喜欢的东西.
     * @param nanosTimeout 等待的最大纳秒数
     * @return {@code true} if acquired; {@code false} if timed out
     * @throws InterruptedException 如果当前线程被中断
     */
    public final boolean tryAcquireNanos(int arg, long nanosTimeout)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        return tryAcquire(arg) ||
                doAcquireNanos(arg, nanosTimeout);
    }

    /**
     * 以独占模式release. 如果{@link #tryRelease}返回true,
     * 通过解除阻塞一个或多个线程实现. 此方法可用于实现方法{@link Lock#unlock}.
     *
     * @param arg release参数. 这个值被传递给{@link #tryRelease},
     *        但没有解释, 可以表示任何你喜欢的东西.
     * @return 从{@link #tryRelease}返回的值
     */
    public final boolean release(int arg) {
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }

    /**
     * 在共享模式下require, 忽略中断. 通过首先调用至少一次{@link #tryAcquireShared}
     * 并成功返回来实现. 否则, 线程将被排队, 可能会反复阻塞和解除阻塞, 调用
     * {@link #tryAcquireShared}直到成功.
     *
     * @param arg acquire参数. 这个值被传递给{@link #tryAcquireShared},
     *        但没有解释, 可以表示任何你喜欢的东西.
     */
    public final void acquireShared(int arg) {
        if (tryAcquireShared(arg) < 0)
            doAcquireShared(arg);
    }

    /**
     * 在共享模式下acquire, 中断时中止. 首先检查中断状态, 然后调用至少一次
     * {@link #tryAcquireShared}并成功返回来实现. 否则, 线程将排队, 可能
     * 会反复阻塞和解除阻塞, 调用{@link #tryAcquireShared}直到成功或线程被中断.
     * @param arg acquire参数. 这个值被传递给{@link #tryAcquireShared},
     *        但没有解释, 可以表示任何你喜欢的东西.
     * @throws InterruptedException 如果当前线程被中断
     */
    public final void acquireSharedInterruptibly(int arg)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        if (tryAcquireShared(arg) < 0)
            doAcquireSharedInterruptibly(arg);
    }

    /**
     * 尝试在共享模式下acquire, 如果中断则中止, 如果给定的超时过期则失败.
     * 通过首先检查中断状态实现, 然后至少调用一次{@link #tryAcquireShared}
     * 并成功返回来实现. 否则, 线程将被排队, 可能会反复阻塞和解除阻塞, 调用
     * {@link #tryAcquireShared}, 直到成功或线程被中断或超时结束.
     *
     * @param arg acquire参数. 该值被传递给{@link #tryAcquireShared},
     *        但不进行解释, 可以表示你喜欢的任何内容.
     * @param nanosTimeout 等待的最大纳秒数
     * @return {@code true} if acquired; {@code false} if timed out
     * @throws InterruptedException 如果当前线程被中断
     */
    public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        return tryAcquireShared(arg) >= 0 ||
                doAcquireSharedNanos(arg, nanosTimeout);
    }

    /**
     * 以共享方式release. 如果{@link #tryReleaseShared}返回true,
     * 通过解除阻塞一个或多个线程实现.
     *
     * @param arg release参数. 该值被传递给{@link #tryReleaseShared},
     *        但不进行解释, 可以表示你喜欢的任何内容.
     * @return 从{@link #tryReleaseShared}返回的值
     */
    public final boolean releaseShared(int arg) {
        if (tryReleaseShared(arg)) {
            doReleaseShared();
            return true;
        }
        return false;
    }

    // Queue检查methods

    /**
     * 查询是否有线程正在等待获取. 请注意, 由于中断和超时导致的取消可能随时发生,
     * 因此{@code true}返回并不能保证任何其他线程都会获得.
     *
     * <p>在实现中, 此操作以恒定时间return.
     *
     * @return {@code true} 如果有其他线程正在等待acquire
     */
    public final boolean hasQueuedThreads() {
        return head != tail;
    }

    /**
     * 查询是否有线程争用这个同步器; 也就是说, 如果一个acquire方法曾经阻塞过.
     *
     * <p>在实现中, 此操作以恒定时间return.
     *
     * @return {@code true} 如果曾经有过争用
     */
    public final boolean hasContended() {
        return head != null;
    }

    /**
     * 返回队列中第一个(等待时间最长的)线程, 如果当前没有线程排队, 则返回{@code null}.
     *
     * <p>在这个实现中, 此操作通常在常量时间内返回, 但如果其他线程并发地修改队列, 则可能在
     * 争用时迭代.
     *
     * @return 队列中第一个(等待时间最长的)线程, 如果当前当前没有线程排队, 则为{@code null}.
     */
    public final Thread getFirstQueuedThread() {
        // 只处理快速路径, 否则中断
        return (head == tail) ? null : fullGetFirstQueuedThread();
    }

    /**
     * fastpath失败时调用的getFirstQueuedThread的版本
     */
    private Thread fullGetFirstQueuedThread() {
        /*
         * 第一个节点通常是head.next, 尝试获取它的thread字段, 确保读取的
         * 一致性: 如果thread字段被清空, 或s.prev不再是head, 那么其他线程
         * 会在我们的一些读取之间并发地执行setHead. 在使用遍历之前, 我们尝试
         * 了两次.
         */
        Node h, s;
        Thread st;
        if (((h = head) != null && (s = h.next) != null &&
                s.prev == head && (st = s.thread) != null) ||
                ((h = head) != null && (s = h.next) != null &&
                        s.prev == head && (st = s.thread) != null))
            return st;

        /*
         * head的next字段可能尚未设置, 或者可能在setHead之后未设置. 所以我们
         * 必须检查tail是否真的是第一个节点. 如果没有, 我们继续, 从tail安全地
         * 穿越到head以找到第一个, 保证终止.
         */

        Node t = tail;
        Thread firstThread = null;
        while (t != null && t != head) {
            Thread tt = t.thread;
            if (tt != null)
                firstThread = tt;
            t = t.prev;
        }
        return firstThread;
    }

    /**
     * 如果给定线程当前正在排队, 则返回true.
     *
     * <p>这个实现遍历队列以确定给定线程是否存在.
     *
     * @param thread the thread
     * @return {@code true} 如果给定的线程在队列中
     * @throws NullPointerException 如果线程为null
     */
    public final boolean isQueued(Thread thread) {
        if (thread == null)
            throw new NullPointerException();
        for (Node p = tail; p != null; p = p.prev)
            if (p.thread == thread)
                return true;
        return false;
    }

    /**
     * 如果第一个排队的线程(如果存在)以排他模式等待, 则返回{@code true}. 如果
     * 此方法返回{@code true}, 并且当前线程正在尝试以共享模式获取(即, 从
     * {@link #tryAcquireShared}调用此方法), 则可以保证当前线程不是第一个排队
     * 的线程. 仅在ReentrantReadWriteLock中用作启发式.
     */
    final boolean apparentlyFirstQueuedIsExclusive() {
        Node h, s;
        return (h = head) != null &&
                (s = h.next)  != null &&
                !s.isShared()         &&
                s.thread != null;
    }

    /**
     * 查询是否有线程等待获取的时间比当前线程长.
     *
     * <p>此方法的调用等效于(但可能比):
     *  <pre> {@code
     * getFirstQueuedThread() != Thread.currentThread() &&
     * hasQueuedThreads()}</pre>
     *
     * <p>请注意, 由于中断和超时导致的取消可能随时发生, 因此返回{@code true}
     * 并不能保证其他线程会在当前线程之前获得. 同样, 在此方法返回{@code false}
     * 后, 由于队列为空, 另一个线程页可能赢得进入队列的竞争.
     *
     * <p>这种方法被设计为由公平同步器使用, 以避免
     * <a href="AbstractQueuedSynchronizer#barging">barging</a>.
     * 如果同步器的{@link #tryAcquire}方法返回{@code true}(除非这是一个可重入的
     * acquire), 则该方法应返回{@code false}, 其{@link #tryAcquireShared}方法
     * 应该返回负值. 例如, 公平、可重入、独占模式同步器的{@code tryAcquire}方法可能
     * 如下所示:
     *
     *  <pre> {@code
     * protected boolean tryAcquire(int arg) {
     *   if (isHeldExclusively()) {
     *     // 可重入的acquire, 增量保持计数
     *     return true;
     *   } else if (hasQueuedPredecessors()) {
     *     return false;
     *   } else {
     *     // try to acquire normally
     *   }
     * }}</pre>
     *
     * @return {@code true} 如果在当前限制之前有一个排队的线程;
     *         如果当前线程位于队列的head或队列为空, 则为{@code false}
     */
    public final boolean hasQueuedPredecessors() {
        // 这一点的正确性屈居于head在tail之前被初始化,
        // 以及如果当前线程在队列中的第一个, 那么head.next是否准确.
        Node t = tail; // 按相反的初始化顺序读取字段
        Node h = head;
        Node s;
        return h != t &&
                ((s = h.next) == null || s.thread != Thread.currentThread());
    }


    //仪表和监测方法

    /**
     * 返回等待获取的线程数的估计值. 该值只是一个估计值, 因为当该方法遍历内部数据结构
     * 时, 线程数可能会动态变化. 此方法设计用于监控系统状态, 而不是用于同步控制.
     *
     * @return 等待获取的估计线程数
     */
    public final int getQueueLength() {
        int n = 0;
        for (Node p = tail; p != null; p = p.prev) {
            if (p.thread != null)
                ++n;
        }
        return n;
    }

    /**
     * 返回包含可能正在等待获取的线程的集合. 因为在构建这个结果时, 实际的线程集合
     * 可能会动态变化, 所以返回的集合只是一个尽力而为的估计. 返回的集合中的元素没有
     * 特定的顺序. 这种方法旨在促进提供更广泛监控设置的子类的构建.
     *
     * @return 线程的集合
     */
    public final Collection<Thread> getQueuedThreads() {
        ArrayList<Thread> list = new ArrayList<Thread>();
        for (Node p = tail; p != null; p = p.prev) {
            Thread t = p.thread;
            if (t != null)
                list.add(t);
        }
        return list;
    }

    /**
     * 返回一个集合, 该集合包含可能 正在以独占模式等待获取的线程. 这与
     * {@link #getQueuedThreads}具有相同的属性, 只是它返回那些由于独占
     * acquire二等待的线程.
     *
     * @return 线程的集合
     */
    public final Collection<Thread> getExclusiveQueuedThreads() {
        ArrayList<Thread> list = new ArrayList<Thread>();
        for (Node p = tail; p != null; p = p.prev) {
            if (!p.isShared()) {
                Thread t = p.thread;
                if (t != null)
                    list.add(t);
            }
        }
        return list;
    }

    /**
     * 返回一个集合, 该集合包含可能正在共享模式 下等待acquire的线程.
     * 这与{@link #getQueuedThreads}具有相同的数下, 只是它返回那些
     * 由于共享acquire而等待的线程.
     *
     * @return 线程的集合
     */
    public final Collection<Thread> getSharedQueuedThreads() {
        ArrayList<Thread> list = new ArrayList<Thread>();
        for (Node p = tail; p != null; p = p.prev) {
            if (p.isShared()) {
                Thread t = p.thread;
                if (t != null)
                    list.add(t);
            }
        }
        return list;
    }

    /**
     * 返回标识此同步器及其状态的字符串.
     * 括号中的状态包括字符串{@code "State ="}, 后跟{@link #getState}的当前值,
     * 以及{@code "nonempty"}或{@code "empty"}, 具体取决于队列是否为空.
     *
     * @return 标识此同步器及其状态的字符串
     */
    public String toString() {
        int s = getState();
        String q  = hasQueuedThreads() ? "non" : "";
        return super.toString() +
                "[State = " + s + ", " + q + "empty queue]";
    }


    // 条件的内部支撑方法

    /**
     * 如果一个节点(通常是最初放置在条件队列中的节点)现在正在等待
     * reacquire获取同步队列, 则返回true.
     * @param node the node
     * @return true if is reacquiring
     */
    final boolean isOnSyncQueue(Node node) {
        if (node.waitStatus == Node.CONDITION || node.prev == null)
            return false;
        if (node.next != null) // 如果有继任者, 则必须在队列中
            return true;
        /*
         * node.prev可以使非null, 但还不在队列中, 因为将其放置在队列中的CAS
         * 可能会失败. 因此, 我们必行从尾部遍历, 以确保它在很多成功了. 在对该
         * 方法的调用中, 它总是在tail附近, 除非CAS失败(这是不可能的), 否则它
         * 会在那里, 所以我们几乎不会遍历太多.
         */
        return findNodeFromTail(node);
    }

    /**
     * 若节点在同步队列中, 则通过从tail向后搜索返回true.
     * 仅在isOnSyncQueue需要时调用.
     * @return true if present
     */
    private boolean findNodeFromTail(Node node) {
        Node t = tail;
        for (;;) {
            if (t == node)
                return true;
            if (t == null)
                return false;
            t = t.prev;
        }
    }

    /**
     * 将节点从条件队列转移到同步队列. 如果成功, 则返回true.
     * @param node the node
     * @return true 如果成功传输(否则节点在发出信号之前被取消)
     */
    final boolean transferForSignal(Node node) {
        /*
         * 如果无法更改waitStatus, 则表示该节点已被取消.
         */
        if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
            return false;

        /*
         * 拼接到队列上, 并尝试设置前置线程的waitStatus以指示线程(可能)正在等待.
         * 如果取消或尝试设置waitStatus失败, 请唤醒以重新同步(在这种情况下,
         * waitStatus可能会暂时错误, 不会早晨跟任何伤害).
         */
        Node p = enq(node);
        int ws = p.waitStatus;
        if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
            LockSupport.unpark(node.thread);
        return true;
    }

    /**
     * 如果有比较, 在取消等待在后将节点传输到同步队列.
     * 如果线程在发出信号 之前被取消, 则返回true.
     *
     * @param node the node
     * @return true 如果在节点发出信号之前取消
     */
    final boolean transferAfterCancelledWait(Node node) {
        if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
            enq(node);
            return true;
        }
        /*
         * 如果我们输给了signal(), 那么在它完成enq()之前我们无法继续.
         * 在不完整的传输过程中取消是罕见的, 也是短暂的, 所以只是旋转.
         */
        while (!isOnSyncQueue(node))
            Thread.yield();
        return false;
    }

    /**
     * 调用具有当前状态值的release; 返回保存的状态.
     * 取消节点并在失败时引发异常.
     * @param node 此等待的条件节点
     * @return 上一个同步状态
     */
    final int fullyRelease(Node node) {
        boolean failed = true;
        try {
            int savedState = getState();
            if (release(savedState)) {
                failed = false;
                return savedState;
            } else {
                throw new IllegalMonitorStateException();
            }
        } finally {
            if (failed)
                node.waitStatus = Node.CANCELLED;
        }
    }

    // 条件的仪表方法

    /**
     * 查询给定的ConditionObject是否使用此同步器作为其锁.
     *
     * @param condition the condition
     * @return {@code true} 如果拥有
     * @throws NullPointerException 如果条件为null
     */
    public final boolean owns(ConditionObject condition) {
        return condition.isOwnedBy(this);
    }

    /**
     * 查询是否有任何线程正在等待与此同步器关联的给定条件. 请注意, 由于超时和中断
     * 可能随时发生, {@code true}返回并不能保证将来的{@code signal}会唤醒任何
     * 线程. 该方法主要用于系统状态的监控.
     *
     * @param condition the condition
     * @return {@code true} 如果有任何正在等待的线程
     * @throws IllegalMonitorStateException 如果未保持独占同步
     * @throws IllegalArgumentException 如果给定条件与该同步器不关联
     * @throws NullPointerException 如果条件为null
     */
    public final boolean hasWaiters(ConditionObject condition) {
        if (!owns(condition))
            throw new IllegalArgumentException("Not owner");
        return condition.hasWaiters();
    }

    /**
     * 返回等待与此同步器关联的给定条件的线程数的估计值. 请注意, 由于超时和中断随时
     * 可能发生, 因此估计值进作为实际等待人数的上限. 此方法设计用于监视系统状态,
     * 而不是用于同步控制.
     *
     * @param condition the condition
     * @return 估计的等待线程数
     * @throws IllegalMonitorStateException 如果未保持独占同步
     * @throws IllegalArgumentException 如果给定条件与该同步器不关联
     * @throws NullPointerException 如果条件为null
     */
    public final int getWaitQueueLength(ConditionObject condition) {
        if (!owns(condition))
            throw new IllegalArgumentException("Not owner");
        return condition.getWaitQueueLength();
    }

    /**
     * 返回一个集合, 其中包含可能正在等待与此同步器关联的给定条件的线程.
     * 因为在构建这个结果时, 实际的线程集合可能会动态变化, 所以返回的集合
     * 只是一个尽力而为的估计. 返回的集合中的元素没有特定的顺序.
     *
     * @param condition the condition
     * @return 线程的集合
     * @throws IllegalMonitorStateException 如果未保持独占同步
     * @throws IllegalArgumentException 如果给定条件与该同步器不关联
     * @throws NullPointerException 如果条件为null
     */
    public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
        if (!owns(condition))
            throw new IllegalArgumentException("Not owner");
        return condition.getWaitingThreads();
    }

    /**
     * 作为{@link Lock}实现基础的{@link AbstractQueuedSynchronizer}的条件实现.
     *
     * <p>该类的方法文档从Lock和Condition用于的角度描述了机制, 而不是行为规范.
     * 该类的导出版本通常需要附带描述依赖于相关{@code AbstractQueuedSynchronizer}
     * 的条件语义的文档.
     *
     * <p>这个恶类时可序列化的, 但所有字段都是瞬态的, 所以反序列化的条件美誉等待程序.
     */
    public class ConditionObject implements Condition, java.io.Serializable {
        private static final long serialVersionUID = 1173984872572414699L;
        /** 条件队列的第一个节点. */
        private transient Node firstWaiter;
        /** 条件队列的最后一个节点. */
        private transient Node lastWaiter;

        /**
         * 创建一个新的{@code ConditionObject}实例.
         */
        public ConditionObject() { }

        // 内部方法

        /**
         * 将新waiter添加到等待队列中.
         * @return 其新的等待节点
         */
        private Node addConditionWaiter() {
            Node t = lastWaiter;
            // 如果最后一个waiter被取消了, 请清空.
            if (t != null && t.waitStatus != Node.CONDITION) {
                unlinkCancelledWaiters();
                t = lastWaiter;
            }
            Node node = new Node(Thread.currentThread(), Node.CONDITION);
            if (t == null)
                firstWaiter = node;
            else
                t.nextWaiter = node;
            lastWaiter = node;
            return node;
        }

        /**
         * 删除并转移节点, 直到命中未取消的节点或未null. 从信号中分离出来部分是为了
         * 鼓励编译器内敛没有waiter的情况.
         * @param first (非null)条件队列上的第一个节点
         */
        private void doSignal(Node first) {
            do {
                if ( (firstWaiter = first.nextWaiter) == null)
                    lastWaiter = null;
                first.nextWaiter = null;
            } while (!transferForSignal(first) &&
                    (first = firstWaiter) != null);
        }

        /**
         * 移除并转移所有节点.
         * @param first (非null)条件队列上的第一个节点
         */
        private void doSignalAll(Node first) {
            lastWaiter = firstWaiter = null;
            do {
                Node next = first.nextWaiter;
                first.nextWaiter = null;
                transferForSignal(first);
                first = next;
            } while (first != null);
        }

        /**
         * 从条件队列中解除已取消的waiter节点的链接. 只在持有锁时调用.
         * 当条件等待期间发生取消时, 以及当lastWaiter被取消时插入新的waiter时,
         * 调用该函数. 在没有信号的情况下, 需要使用此方法来避免垃圾保留. 因此,
         * 尽管它可能需要一次完整的遍历, 但只有在没有信号的情况下发生超时或取消时,
         * 它才会发挥作用. 它遍历所有节点, 而不是在一个特定的目标上停止, 以解除
         * 指向垃圾节点的所有指针的链接, 二部 需要在取消风暴期间进行多次重新遍历.
         */
        private void unlinkCancelledWaiters() {
            Node t = firstWaiter;
            Node trail = null;
            while (t != null) {
                Node next = t.nextWaiter;
                if (t.waitStatus != Node.CONDITION) {
                    t.nextWaiter = null;
                    if (trail == null)
                        firstWaiter = next;
                    else
                        trail.nextWaiter = next;
                    if (next == null)
                        lastWaiter = trail;
                }
                else
                    trail = t;
                t = next;
            }
        }

        // public methods

        /**
         * 将等待时间最长的线程(如果存在)从此条件的等待队列移动到拥有锁的等待队列.
         *
         * @throws IllegalMonitorStateException 如果{@link #isHeldExclusively}返回{@code false}
         */
        public final void signal() {
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
            Node first = firstWaiter;
            if (first != null)
                doSignal(first);
        }

        /**
         * 将此条件的所有线程从等待队列移动到拥有锁的等待队列.
         *
         * @throws IllegalMonitorStateException 如果{@link #isHeldExclusively}返回{@code false}
         */
        public final void signalAll() {
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
            Node first = firstWaiter;
            if (first != null)
                doSignalAll(first);
        }

        /**
         * 实现不间断条件等待.
         * <ol>
         * <li> 保存{@link #getState}返回的锁状态.
         * <li> 以保存的状态作为参数调用{@link #release}, 如果失败则抛出
         *      IllegalMonitorStateException.
         * <li> 等待信号.
         * <li> 通过调用{@link #acquire}的特殊版本, 以保持状态作为参数来重新acquire.
         * </ol>
         */
        public final void awaitUninterruptibly() {
            Node node = addConditionWaiter();
            int savedState = fullyRelease(node);
            boolean interrupted = false;
            while (!isOnSyncQueue(node)) {
                LockSupport.park(this);
                if (Thread.interrupted())
                    interrupted = true;
            }
            if (acquireQueued(node, savedState) || interrupted)
                selfInterrupt();
        }

        /*
         * 对于可中断的等待, 我们需要个跟踪是否抛出InterruptedException,
         * 如果在阻塞条件下中断, 如果在条件下被阻止时被中断, 而如果在等待重新获取时
         * 被阻止, 则重新中断当前线程.
         */

        /** 模式意味着退出等待时重新中断 */
        private static final int REINTERRUPT =  1;
        /** 模式意味着在退出等待时抛出InterruptedException */
        private static final int THROW_IE    = -1;

        /**
         * 检查中断, 如果在发出信号之前中断, 则返回THROW_IE, 如果在发出
         * 信号之后中断, 则返回REINTERRUPT, 如果未中断则返回0.
         */
        private int checkInterruptWhileWaiting(Node node) {
            return Thread.interrupted() ?
                    (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
                    0;
        }

        /**
         * 抛出InterruptedException、重新中断当前线程或不执行任何操作,
         * 具体取决于模式.
         */
        private void reportInterruptAfterWait(int interruptMode)
                throws InterruptedException {
            if (interruptMode == THROW_IE)
                throw new InterruptedException();
            else if (interruptMode == REINTERRUPT)
                selfInterrupt();
        }

        /**
         * 实现可中断条件等待.
         * <ol>
         * <li> 如果当前线程被中断, 则抛出InterruptedException.
         * <li> 保存{@link #getState}返回的锁定状态.
         * <li> 以保存时的状态为参数调用{@link #release}, 如果失败则抛出
         *      IllegalMonitorStateException.
         * <li> 阻塞, 直到发出信号或中断.
         * <li> 通过调用{@link #acquire}的专用版本并将保存的状态作为参数来重新获取.
         * <li> 如果在步骤4中被阻止时被中断, 则抛出InterruptedException.
         * </ol>
         */
        public final void await() throws InterruptedException {
            if (Thread.interrupted())
                throw new InterruptedException();
            Node node = addConditionWaiter();
            int savedState = fullyRelease(node);
            int interruptMode = 0;
            while (!isOnSyncQueue(node)) {
                LockSupport.park(this);
                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                    break;
            }
            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                interruptMode = REINTERRUPT;
            if (node.nextWaiter != null) // 如果取消则进行清理
                unlinkCancelledWaiters();
            if (interruptMode != 0)
                reportInterruptAfterWait(interruptMode);
        }

        /**
         * 实现定时条件等待.
         * <ol>
         * <li> 如果当前线程被中断, 则抛出InterruptedException.
         * <li> 保存{@link #getState}返回的锁定状态.
         * <li> 以保存的状态为参数调用{@link #release}, 如果失败则抛出
         *      IllegalMonitorStateException.
         * <li> 阻塞, 直到发出信号、中断或超时.
         * <li> 通过调用{@link #acquire}的专用版本并将保持的 状态作为参数来重新获取.
         * <li> 如果在步骤4中被阻止时被中断, 则抛出InterruptedException.
         * </ol>
         */
        public final long awaitNanos(long nanosTimeout)
                throws InterruptedException {
            if (Thread.interrupted())
                throw new InterruptedException();
            Node node = addConditionWaiter();
            int savedState = fullyRelease(node);
            final long deadline = System.nanoTime() + nanosTimeout;
            int interruptMode = 0;
            while (!isOnSyncQueue(node)) {
                if (nanosTimeout <= 0L) {
                    transferAfterCancelledWait(node);
                    break;
                }
                if (nanosTimeout >= spinForTimeoutThreshold)
                    LockSupport.parkNanos(this, nanosTimeout);
                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                    break;
                nanosTimeout = deadline - System.nanoTime();
            }
            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                interruptMode = REINTERRUPT;
            if (node.nextWaiter != null)
                unlinkCancelledWaiters();
            if (interruptMode != 0)
                reportInterruptAfterWait(interruptMode);
            return deadline - System.nanoTime();
        }

        /**
         * 实现绝对定时条件等待.
         * <ol>
         * <li> 如果当前线程被中断, 则抛出InterruptedException.
         * <li> 保存{@link #getState}返回的锁定状态.
         * <li> 以保存的状态为参数调用{@link #release}, 如果失败则抛出
         *      IllegalMonitorStateException.
         * <li> 阻塞, 直到发出信号、中断或超时.
         * <li> 通过调用{@link #acquire}的专用版本并将保存的状态作为参数来重新获取.
         * <li> 如果在步骤4中被阻止时被中断, 则抛出InterruptedException.
         * <li> 如果在步骤4中被阻止时超时, 则返回false, 否则返回true.
         * </ol>
         */
        public final boolean awaitUntil(Date deadline)
                throws InterruptedException {
            long abstime = deadline.getTime();
            if (Thread.interrupted())
                throw new InterruptedException();
            Node node = addConditionWaiter();
            int savedState = fullyRelease(node);
            boolean timedout = false;
            int interruptMode = 0;
            while (!isOnSyncQueue(node)) {
                if (System.currentTimeMillis() > abstime) {
                    timedout = transferAfterCancelledWait(node);
                    break;
                }
                LockSupport.parkUntil(this, abstime);
                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                    break;
            }
            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                interruptMode = REINTERRUPT;
            if (node.nextWaiter != null)
                unlinkCancelledWaiters();
            if (interruptMode != 0)
                reportInterruptAfterWait(interruptMode);
            return !timedout;
        }

        /**
         * 实现定时条件等待.
         * <ol>
         * <li> 如果当前线程被中断, 则抛出InterruptedException.
         * <li> 保存{@link #getState}返回的锁定状态.
         * <li> 以保存的状态为参数调用{@link #release}, 如果失败则抛出
         *      IllegalMonitorStateException.
         * <li> 阻塞, 直到发出信号、中断或超时.
         * <li> 通过调用{@link #acquire}的专用版本并将保存的状态作为参数来重新获取.
         * <li> 如果在步骤4中被阻止时被中断, 则抛出InterruptedException.
         * <li> 如果在步骤4中被阻止时超时, 则返回false, 否则返回true.
         * </ol>
         */
        public final boolean await(long time, TimeUnit unit)
                throws InterruptedException {
            long nanosTimeout = unit.toNanos(time);
            if (Thread.interrupted())
                throw new InterruptedException();
            Node node = addConditionWaiter();
            int savedState = fullyRelease(node);
            final long deadline = System.nanoTime() + nanosTimeout;
            boolean timedout = false;
            int interruptMode = 0;
            while (!isOnSyncQueue(node)) {
                if (nanosTimeout <= 0L) {
                    timedout = transferAfterCancelledWait(node);
                    break;
                }
                if (nanosTimeout >= spinForTimeoutThreshold)
                    LockSupport.parkNanos(this, nanosTimeout);
                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                    break;
                nanosTimeout = deadline - System.nanoTime();
            }
            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                interruptMode = REINTERRUPT;
            if (node.nextWaiter != null)
                unlinkCancelledWaiters();
            if (interruptMode != 0)
                reportInterruptAfterWait(interruptMode);
            return !timedout;
        }

        //  仪表支架

        /**
         * 如果此条件时由给定的同步对象创建的, 则返回true.
         *
         * @return {@code true} 如果拥有
         */
        final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
            return sync == AbstractQueuedSynchronizer.this;
        }

        /**
         * 查询是否有线程正在等待此条件.
         * 实现{@link AbstractQueuedSynchronizer#hasWaiters(ConditionObject)}.
         *
         * @return {@code true} 如果有任何正在等待的线程
         * @throws IllegalMonitorStateException 如果{@link #isHeldExclusively}返回{@code false}
         */
        protected final boolean hasWaiters() {
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
            for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
                if (w.waitStatus == Node.CONDITION)
                    return true;
            }
            return false;
        }

        /**
         * 返回等待此条件的线程数的估计值.
         * 实现{@link AbstractQueuedSynchronizer#getWaitQueueLength(ConditionObject)}.
         *
         * @return 估计的等待线程数
         * @throws IllegalMonitorStateException 如果{@link #isHeldExclusively}返回{@code false}
         */
        protected final int getWaitQueueLength() {
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
            int n = 0;
            for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
                if (w.waitStatus == Node.CONDITION)
                    ++n;
            }
            return n;
        }

        /**
         * 返回一个集合, 该集合包含可能正在等待此Condition的线程.
         * 实现{@link AbstractQueuedSynchronizer#getWaitingThreads(ConditionObject)}.
         *
         * @return 线程的集合
         * @throws IllegalMonitorStateException 如果{@link #isHeldExclusively}返回{@code false}
         */
        protected final Collection<Thread> getWaitingThreads() {
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
            ArrayList<Thread> list = new ArrayList<Thread>();
            for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
                if (w.waitStatus == Node.CONDITION) {
                    Thread t = w.thread;
                    if (t != null)
                        list.add(t);
                }
            }
            return list;
        }
    }

    /**
     * Setup以支持compareAndSet. 我们需要在这里原生地实现这一点: 为了允许未来
     * 的增强, 我们不能显式地对AtomicInteger进行子类化, 否则这将是高效和有用的.
     * 因此, 作为邪恶中的较小者, 我们使用特点内部API本地实现. 当我们这样做的时候,
     * 我们对其他CASable字段也这样做(否则可以用原子字段更新器来完成).
     */
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long stateOffset;
    private static final long headOffset;
    private static final long tailOffset;
    private static final long waitStatusOffset;
    private static final long nextOffset;

    static {
        try {
            stateOffset = unsafe.objectFieldOffset
                    (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
            headOffset = unsafe.objectFieldOffset
                    (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
            tailOffset = unsafe.objectFieldOffset
                    (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
            waitStatusOffset = unsafe.objectFieldOffset
                    (Node.class.getDeclaredField("waitStatus"));
            nextOffset = unsafe.objectFieldOffset
                    (Node.class.getDeclaredField("next"));

        } catch (Exception ex) { throw new Error(ex); }
    }

    /**
     * CAS head字段. 仅由enq使用.
     */
    private final boolean compareAndSetHead(Node update) {
        return unsafe.compareAndSwapObject(this, headOffset, null, update);
    }

    /**
     * CAS tail字段. 仅由enq使用.
     */
    private final boolean compareAndSetTail(Node expect, Node update) {
        return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
    }

    /**
     * 节点的CAS waitStatus字段.
     */
    private static final boolean compareAndSetWaitStatus(Node node,
                                                         int expect,
                                                         int update) {
        return unsafe.compareAndSwapInt(node, waitStatusOffset,
                expect, update);
    }

    /**
     * 节点的CAS next字段.
     */
    private static final boolean compareAndSetNext(Node node,
                                                   Node expect,
                                                   Node update) {
        return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
    }
}
